home *** CD-ROM | disk | FTP | other *** search
- /*
- external_primitive.c
-
- an example external primitive.
-
- by Patrick C. Beard.
-
- <Revision History>
- 01/01/95 pcb Created.
- 02/28/95 pcb Compiling for PPC.
- */
-
- #ifndef __TYPES__
- #include <Types.h>
- #endif
- #ifndef __MEMORY__
- #include <Memory.h>
- #endif
-
- #include "external_primitive.h"
-
- #if !defined(powerc)
- #ifdef THINK_C
- #include <SetUpA4.h>
- #define InitGlobals() RememberA0()
- #define OpenGlobals() SetUpA4()
- #define CloseGlobals() RestoreA4()
- #endif /* THINK_C */
- #else
- #define InitGlobals()
- #define OpenGlobals()
- #define CloseGlobals()
- #endif
-
- #if !defined(InitGlobals)
- #error "Unsupported configuration."
- #endif
-
- ExternalPrimitiveCallbacks* callbacks;
- ExternalPrimitiveObjects* objects;
-
- ExternalPrimitiveCallbacks* GetCallbacks()
- {
- ExternalPrimitiveCallbacks* cb;
- OpenGlobals();
- cb = callbacks;
- CloseGlobals();
- return cb;
- }
-
- ExternalPrimitiveObjects* GetObjects()
- {
- ExternalPrimitiveObjects* ob;
- OpenGlobals();
- ob = objects;
- CloseGlobals();
- return ob;
- }
-
- void GetSupport(ExternalPrimitiveCallbacks** cb, ExternalPrimitiveObjects** ob)
- {
- OpenGlobals();
- *cb = callbacks;
- *ob = objects;
- CloseGlobals();
- }
-
- static Object debug_string(Object messageObj)
- {
- ExternalPrimitiveCallbacks* callbacks;
- Str255 message;
-
- message[0] = BYTESTRSIZE(messageObj);
- BlockMoveData(BYTESTRVAL(messageObj), message + 1, message[0]);
-
- DebugStr(message);
-
- // getting an object's value the hard way.
- callbacks = GetCallbacks();
- return callbacks->symbol_value(callbacks->make_symbol("%unspecified"));
- }
-
- static Object new_ptr(Object sizeObj)
- {
- ExternalPrimitiveCallbacks* callbacks;
- Object plus_symbol;
- Object one;
- Object expr_list;
- Ptr ptr;
-
- callbacks = GetCallbacks();
-
- // always add an extra byte to show how to use eval and apply.
- plus_symbol = callbacks->make_symbol("+"); // create a "+" symbol.
- one = MAKE_INT(1); // create a 1 object.
- expr_list = callbacks->listem(plus_symbol, sizeObj, one, NULL); // (+ sizeObj 1)
- sizeObj = callbacks->eval(expr_list); // evaluate the list.
-
- ptr = NewPtr(INTVAL(sizeObj));
- if (!ptr) {
- callbacks->error("%new-ptr: couldn't allocate requested size", sizeObj, NULL);
- }
-
- return callbacks->make_foreign_ptr(ptr);
- }
-
- static Object dispose_ptr(Object ptrObj)
- {
- ExternalPrimitiveCallbacks* callbacks;
- ExternalPrimitiveObjects* objects;
-
- GetSupport(&callbacks, &objects);
-
- if (!FOREIGNP(ptrObj)) {
- callbacks->error("%dispose-ptr: argument not a foreign pointer", ptrObj, NULL);
- }
-
- DisposePtr((Ptr)FOREIGNPTR(ptrObj));
- FOREIGNPTR(ptrObj) = 0;
-
- return objects->unspecified_object;
- }
-
- static void set_primitive(struct primitive* prim, char *name,
- enum primtype prim_type, Object (*fun) ())
- {
- prim->name = name;
- prim->prim_type = prim_type;
- prim->fun = fun;
- }
-
- void main(ExternalPrimitiveSupport* support)
- {
- struct primitive external_prims[3];
-
- InitGlobals();
- OpenGlobals();
-
- // initialize some globals.
- callbacks = support->callbacks;
- objects = support->objects;
-
- // initialize the primitives.
- set_primitive(&external_prims[0], "%debug-string", prim_1, &debug_string);
- set_primitive(&external_prims[1], "%new-ptr", prim_1, &new_ptr);
- set_primitive(&external_prims[2], "%dispose-ptr", prim_1, &dispose_ptr);
-
- // install the primitives.
- callbacks->init_prims(3, external_prims);
-
- CloseGlobals();
- }
-